<?php

namespace App\Http\Model;

use App\Lib\Search;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class CrossRoomPkRecord extends Base
{
    protected $crossRoomPkRecord = 'cross_room_pk_record';//PK记录
    protected $crossRoomPkAdminSet = 'cross_room_pk_admin_set';//后台PK设置
    protected $roomTable = 'room';//房间表
    protected $crossRoomPkStream = 'cross_room_pk_stream';//房间流水pk
    protected $crossRoomPkMissionStream = 'cross_room_pk_mission_stream';//每日任务
    protected $crossRoomPkMissionGiftConfig = 'cross_room_pk_mission_gift_config';//每日任务送礼配置表

    protected $redisBackPksetInfo = 'CROSS:ROOM:BACK:PKSETINFO';//后台配置PK缓存 string BACK:PKSETINFO=>{json}
    protected $missionPkGift = 'CROSS:ROOM:PK:MISSIONGIFT';//每日任务奖励数据
    protected $redis_room_cache = 'CACHE:ROOM:';

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }

    //记录PK发起数据
    public function recordPk($data, $sendId = 0){
        if(!empty($sendId)){
            
            $status = DB::table($this->crossRoomPkRecord)->where('id',$sendId)->update($data);
            return $sendId;
        }else{
            $status = DB::table($this->crossRoomPkRecord)->insertGetId($data);
            return $status;
        }
        
    }

    //查询数据是否存在
    public function issetData($roomId, $toRoomId, $status = 0, $send_status=[0]){
        $todayEnd = Carbon::today()->endOfDay()->toDateTimeString();//一天结束
        $isset = DB::table($this->crossRoomPkRecord)
                ->where(['from_room_id'=>$roomId,'to_room_id'=>$toRoomId,'pk_status'=>$status])
                ->whereIn('send_status',$send_status)
                ->where('created_at','<=',$todayEnd)
                ->exists();
        return $isset;
    }

    //邀请PK详情
    public function getPkInfo($sendId){
        $info = DB::table($this->crossRoomPkRecord)->where('id',$sendId)->first();
        $info = self::objToArray($info);
        return $info;
    }

    //更新PK记录
    public function upRecordPk($updata, $sendId){
        $status = DB::table($this->crossRoomPkRecord)->where('id',$sendId)->update($updata);
        return $status;
    }

    //更新房间默认
    public function upRoomModel($fromRoomId, $myRoomId){
        $status = DB::table($this->roomTable)->whereIn('room_id',[$fromRoomId,$myRoomId])->update(['room_mode'=>6]);
        $roomIds = [$fromRoomId,$myRoomId];
        //房间变成跨房后取消所有对应房间邀请
        DB::table($this->crossRoomPkRecord)->whereIn('from_room_id',$roomIds)->where('pk_status',0)->where('send_status',0)->update(['send_status'=>3,'to_user_id'=>11]);
        foreach($roomIds as $roomId){
            Redis::DEL($this->redis_room_cache . $roomId);
            $search = new Search();
            $search->delRoom($roomId);
        }
        return $status;
    }

    //获取后台配置的PK时间长
    public function getPkMinutes(){
        $setInfo = Redis::get($this->redisBackPksetInfo);
        if(!empty($setInfo)){
            $setInfo = json_decode($setInfo,true);
        }else{
            $setInfo = DB::table($this->crossRoomPkAdminSet)->where('status',1)->first();
            $setInfo = self::objToArray($setInfo);
            if(!empty($setInfo)){
                Redis::set($this->redisBackPksetInfo,json_encode($setInfo));
            } 
        }
        return $setInfo;
    }

    //获取房间pk列表
    public function getPkPoolData($roomId){
        $startDay = Carbon::today()->startOfDay()->toDateTimeString();
        $endDay = Carbon::today()->endOfDay()->toDateTimeString();
        $data = DB::table($this->roomTable)
                ->leftJoin('cross_room_pk_stream','room.room_id','cross_room_pk_stream.room_id')
                ->select(DB::raw('SUM(zb_cross_room_pk_stream.room_point) as point,zb_room.room_id,zb_room.name,zb_room.image'))
                ->where('cross_room_pk_stream.created_at','>=',$startDay)
                ->where('cross_room_pk_stream.created_at','<=',$endDay)
                ->where('room.room_id',$roomId)
                ->first();
        $data = self::objToArray($data);
        return $data;
    }

    //获取房间是否在匹配中
    public function issetWatting($roomId, $pkStatus, $sendStatus){
        $startDay = Carbon::today()->startOfDay()->toDateTimeString();
        $endDay = Carbon::today()->endOfDay()->toDateTimeString();
        $data = DB::table($this->crossRoomPkRecord)
                ->whereRaw("(from_room_id =?) AND created_at>=? AND created_at<=? AND pk_status=? AND send_status=?",[$roomId,$startDay,$endDay,$pkStatus,$sendStatus])
                ->first();
        $data = self::objToArray($data);
        return $data;
    }

    //获取房间信息
    public function get_room($page, $limit, $finalArr, $roomId){
        $offset = ($page-1)*$limit;
        $data = DB::table($this->roomTable)
                ->where('room_id','!=',$roomId)
                ->whereIn('room_id',$finalArr)
                ->orderByRaw(DB::raw("find_in_set(room_id,'".implode(',',$finalArr)."')"))
                ->offset($offset)
                ->limit($limit)
                ->get();
        return self::objToArray($data);
    }

    //查看房间是否在PK记录表中
    public function issetPkRecord($roomId, $pkStatus=4, $sendStatus=1){
        $startDay = Carbon::today()->startOfDay()->toDateTimeString();
        $endDay = Carbon::today()->endOfDay()->toDateTimeString();
        $data = DB::table($this->crossRoomPkRecord)
                ->whereRaw("(from_room_id =? or to_room_id =?) AND created_at>=? AND created_at<=? AND pk_status=? AND send_status=?",[$roomId,$roomId,$startDay,$endDay,$pkStatus,$sendStatus])
                ->first();
        $data = self::objToArray($data);
        return $data;
    }
    
    //增加送礼流水记录
    public function insetRecord($insert){
        $status = DB::table($this->crossRoomPkStream)->insert($insert);
        return $status;
    }


    //查看送礼PK是否是首个送礼的用户
    public function checkFirstGift($user_id,$roomId,$pkStart,$pkEnd){
        $roomRecord = $this->issetPkRecord($roomId, 4, 1);
        if(!empty($roomRecord)){
            $roomIds = [$roomRecord['from_room_id'],$roomRecord['to_room_id']];
            $count = DB::table($this->crossRoomPkStream)->whereIn('room_id',$roomIds)->where('created_at','>=',$pkStart)->where('created_at','<=',$pkEnd)->count();
            return $count;
        }else{
            return 1;
        }
        
    }

    //查看用户是否领取或者完成任务
    public function getMissionStatus($user_id){
        $startDay = Carbon::today()->startOfDay()->toDateTimeString();
        $endDay = Carbon::today()->endOfDay()->toDateTimeString();
        $data = DB::table($this->crossRoomPkMissionStream)->where('user_id',$user_id)->where('created_at','>=',$startDay)->where('created_at','<=',$endDay)->get();
        $data = self::objToArray($data);
        return $data;
    }

    //获取任务完成详情
    public function getMissionInfo($user_id, $awardId){
        $data = DB::table($this->crossRoomPkMissionStream)->where('user_id',$user_id)->where('id',$awardId)->first();
        $data = self::objToArray($data);
        return $data;
    }

    //获取实时榜单送礼数据
    public function getNowRank($roomId, $startDay='', $endDay='', $limit=200){
        if(empty($startDay)){
            $startDay = Carbon::today()->startOfDay()->toDateTimeString();
        }
        if(empty($endDay)){
            $endDay = Carbon::today()->endOfDay()->toDateTimeString();
        }
        
        //获取统计好的数据
        $model = DB::table($this->crossRoomPkStream)
        ->select(DB::raw('sum(point+award_point) as `point`,from_user_id,room_id'))
        ->where("room_id",$roomId)
        ->where("created_at",'>=',$startDay)
        ->where("created_at",'<=',$endDay)
        ->groupBy('from_user_id');
        //重新分页统计好的数据
        $res = DB::table(DB::raw("({$model->toSql()}) as other"))
            ->mergeBindings($model)
            ->orderBy('point','desc')
            ->limit($limit)
            ->get();
        $res = self::objToArray($res);
        return $res;
    }

    //获取参与PK的人数
    public function getNowRankUser($roomId, $startDay='', $endDay=''){
        if(empty($startDay)){
            $startDay = Carbon::today()->startOfDay()->toDateTimeString();
        }
        if(empty($endDay)){
            $endDay = Carbon::today()->endOfDay()->toDateTimeString();
        }
        $count = DB::table($this->crossRoomPkStream)
                ->select(DB::raw('COUNT(DISTINCT(from_user_id)) as count'))
                ->where("room_id",$roomId)
                ->where("created_at",'>=',$startDay)
                ->where("created_at",'<=',$endDay)
                ->first();
        $count = self::objToArray($count);
        return $count;
    }

    //获取本周送出的钻石数
    public function getWeekRoomDiamond($roomId){
        $weekStart = Carbon::today()->startOfWeek()->toDateTimeString();
        $weekEnd = Carbon::today()->endOfWeek()->toDateTimeString();
        $point = DB::table($this->crossRoomPkStream)
                ->where("room_id",$roomId)
                ->where("created_at",'>=',$weekStart)
                ->where("created_at",'<=',$weekEnd)
                ->sum('point');
        return $point;
    }

    //获取本周用户参与本房间PK的人数
    public function getWeekRoomUser($roomId){
        $weekStart = Carbon::today()->startOfWeek()->toDateTimeString();
        $weekEnd = Carbon::today()->endOfWeek()->toDateTimeString();
        $count = DB::table($this->crossRoomPkStream)
                ->select(DB::raw('COUNT(DISTINCT(from_user_id)) as count'))
                ->where("room_id",$roomId)
                ->where("created_at",'>=',$weekStart)
                ->where("created_at",'<=',$weekEnd)
                ->first();
        $count = self::objToArray($count);
        return $count;
    }

    //获取本周房间参与用户排行榜
    public function getWeekRoomRank($roomId, $limit){
        $weekStart = Carbon::today()->startOfWeek()->toDateTimeString();
        $weekEnd = Carbon::today()->endOfWeek()->toDateTimeString();
        //获取统计好的数据
        $model = DB::table($this->crossRoomPkStream)
        ->select(DB::raw('sum(point+award_point) as `point`,from_user_id,room_id'))
        ->where("room_id",$roomId)
        ->where("created_at",'>=',$weekStart)
        ->where("created_at",'<=',$weekEnd)
        ->groupBy('room_id');
        //重新分页统计好的数据
        $res = DB::table(DB::raw("({$model->toSql()}) as other"))
            ->mergeBindings($model)
            ->orderBy('point','desc')
            ->limit($limit)
            ->get();
        $res = self::objToArray($res);
        return $res;
    }

    //获取本周PK记录
    public function getPkHistory($roomId, $page, $limit){
        $offset = ($page-1) * $limit;
        $list = DB::table($this->crossRoomPkRecord)
                ->whereRaw("(from_room_id =? or to_room_id =?) AND send_status=?",[$roomId,$roomId,1])
                ->whereIn('pk_status',[1,2,3])
                ->orderBy('created_at','desc')
                ->offset($offset)
                ->limit($limit)
                ->get();
        $list = self::objToArray($list);
        return $list;
    }

    //获取房间流水总
    public function getPointCount($roomId, $startTime, $endTime){
        $count = DB::table($this->crossRoomPkStream)
                ->where('room_id',$roomId)
                ->where('created_at','>=', $startTime)
                ->where('created_at','<=', $endTime)
                ->sum('room_point');
        return $count;
    }

    //结算房间PK
    public function endPk($sendId, $data){
        $status = DB::table($this->crossRoomPkRecord)->where('id',$sendId)->update($data);
        return $status;
    }

    //更新房间模式
    public function updateRoomModel($roomIds,$data){
        $status = DB::table($this->roomTable)->whereIn('room_id',$roomIds)->update($data);
        foreach($roomIds as $roomId){
            Redis::DEL($this->redis_room_cache . $roomId);
            $search = new Search();
            $search->delRoom($roomId);
        }
        
        return $status;
    }

    //获取参与用户贡献值
    public function getJoinUserData($roomIds,$pkStart, $pkEnd){
        $data = DB::table($this->crossRoomPkStream)->select(DB::raw('SUM(point+award_point) as total,from_user_id'))->whereIn('room_id',$roomIds)->where('created_at','>=',$pkStart)->where('created_at','<=',$pkEnd)->groupBy('from_user_id')->get();
        $data = self::objToArray($data);
        return $data;
    }

    //获取PK所有房间
    public function getAllPkRecord($user_id){
        $data = DB::table($this->crossRoomPkStream)->select(DB::raw('SUM(room_point) as roomTotal,room_id'))->where('from_user_id',$user_id)->groupBy('room_id')->orderBy('created_at','desc')->limit(200)->get();
        $data = self::objToArray($data);
        return $data;
    }

    //获取PK房间记录我的PK查询
    public function getPkList($roomId){
        $data = DB::table($this->crossRoomPkRecord)->whereRaw("(from_room_id =? or to_room_id =?)  AND send_status=?",[$roomId,$roomId,1])->whereIn('pk_status',[1,2,3])->orderBy('created_at','desc')->limit(200)->get();
        $data = self::objToArray($data);
        return $data;
    }

    //获取我参与PK的贡献值
    public function getPointMy($user_id,$roomId,$start,$end){
        $data = DB::table($this->crossRoomPkStream)->select(DB::raw('SUM(point+award_point) as total,from_user_id'))->where(['room_id'=>$roomId,'from_user_id'=>$user_id])->where('created_at','>=',$start)->where('created_at','<=',$end)->first();
        $data = self::objToArray($data);
        return $data;
    }

    //获取每日任务奖励列表
    public function getMissionGift(){
        $missionArr = Redis::get($this->missionPkGift);
        if(!empty($missionArr)){
            $missionArr = json_decode($missionArr,true);
        }else{
            $missionArr = DB::table($this->crossRoomPkMissionGiftConfig)->where('status',1)->get();
            $missionArr = self::objToArray($missionArr);
            Redis::SET($this->missionPkGift,json_encode($missionArr));
            Redis::EXPIRE($$this->missionPkGift,7*86400);
        }
        return $missionArr;
    }

    //完成任务记录
    public function insertMission($insert){
        $status = DB::table($this->crossRoomPkMissionStream)->insert($insert);
        return $status;
    }

    //领取更新任务
    public function updateMission($id){
        $status = DB::table($this->crossRoomPkMissionStream)->where('id',$id)->update(['send_status'=>1,'updated_at'=>Carbon::now()->toDateTimeString()]);
        return $status;
    }
}